//
//  LVSayHelloElectricWavesView.m
//  LEVE
//
//  Created by 王若聪 on 2017/3/8.
//  Copyright © 2017年 dashuju. All rights reserved.
//

#import "LVSayHelloElectricWavesView.h"

@interface WaveObject : NSObject
@property (nonatomic, strong) CAShapeLayer *shapeLayer;
@property (nonatomic, strong) CAAnimation *waveAnimation;
@property (nonatomic, assign) CGFloat height;
@end
@implementation WaveObject
@end

@interface LVSayHelloElectricWavesView ()
@property (nonatomic, strong) NSTimer *waveTimer;
@property (nonatomic, strong) NSMutableArray *waveObjects;
@property (nonatomic, strong) NSTimer *soundTimer;
@property (nonatomic, strong) NSMutableArray *soundWaveObjects;
@end

static CGFloat straightLineLength = 0.2;
static CGFloat waveWidthValue = 4.0;
static int waveObjectCount = 140;

@implementation LVSayHelloElectricWavesView{
    CGFloat _waveWidth;
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _waveObjects = [NSMutableArray array];
        _soundWaveObjects = [NSMutableArray array];
        _waveWidth = waveWidthValue;
        
        
        self.hidden = YES;

    }
    
    return self;
}

- (void)setWaveWidth:(CGFloat)width
{
    _waveWidth = width;
}

- (void)showWaveView
{
    self.hidden = YES;
    
    for (NSInteger i = 0; i < waveObjectCount; i++) {
        WaveObject *aWaveObject = [self gernerateWaveObject];
        aWaveObject.shapeLayer.position = CGPointMake(_waveWidth/2.0 + i * _waveWidth, self.bounds.size.height / 2);
        [self.layer addSublayer:aWaveObject.shapeLayer];
        [_soundWaveObjects addObject:aWaveObject];
    }
    [self setSoundTimerWithTime:0.15];

    [self performSelector:@selector(showMeNow) withObject:nil afterDelay:0.3];
        
}

- (void)showMeNow{
    self.hidden = NO;
}

- (void)addAnimationToSoundeWaveLayer:(NSTimer *)timer
{
    NSMutableArray *temWaveObjects = [NSMutableArray array];
    @synchronized(_waveObjects) {
        temWaveObjects = _soundWaveObjects;

    }
    
    NSInteger count = temWaveObjects.count;
    if (0 == count) {
        return;
    }
    
    for (NSInteger i = 0; i < count; i++) {
        WaveObject *soundWaveObject = temWaveObjects[i];
        CAShapeLayer *soundeWaveLayer = soundWaveObject.shapeLayer;
        CGFloat newHeight = arc4random() % (NSInteger)(self.bounds.size.height / 4);
        CGFloat oldHeight = soundWaveObject.height;
        
        UIBezierPath *beginPath = [UIBezierPath bezierPath];
        [beginPath moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
        [beginPath addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
        [beginPath addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 - oldHeight) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 + oldHeight)];
        [beginPath addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
        
        UIBezierPath *middlePath1 = [UIBezierPath bezierPath];
        [middlePath1 moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
        [middlePath1 addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
        [middlePath1 addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 - (oldHeight + (newHeight - oldHeight) / 10)) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 + (oldHeight + (newHeight - oldHeight) / 10))];
        [middlePath1 addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
        
        UIBezierPath *middlePath2 = [UIBezierPath bezierPath];
        [middlePath2 moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
        [middlePath2 addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
        [middlePath2 addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 - (oldHeight + (newHeight - oldHeight) / 4)) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 + (oldHeight + (newHeight - oldHeight) / 4))];
        [middlePath2 addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
        
        UIBezierPath *middlePath3 = [UIBezierPath bezierPath];
        [middlePath3 moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
        [middlePath3 addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
        [middlePath3 addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 - (oldHeight + (newHeight - oldHeight) / 2)) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 + (oldHeight + (newHeight - oldHeight) / 2))];
        [middlePath3 addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
        
        UIBezierPath *endPath = [UIBezierPath bezierPath];
        [endPath moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
        [endPath addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
        [endPath addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 - newHeight) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2 + newHeight)];
        [endPath addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
        
        CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"path"];
        pathAnimation.values = @[(__bridge id _Nullable)(beginPath.CGPath), (__bridge id _Nullable)(middlePath1.CGPath), (__bridge id _Nullable)(middlePath2.CGPath), (__bridge id _Nullable)(middlePath3.CGPath),  (__bridge id _Nullable)(endPath.CGPath)];
        pathAnimation.duration = 0.5;
        pathAnimation.calculationMode = kCAAnimationCubic;
        
        soundeWaveLayer.path = endPath.CGPath;
        soundWaveObject.height = newHeight;
        
        [soundeWaveLayer addAnimation:pathAnimation forKey:@""];
    }
}

- (void)setSoundTimerWithTime:(CGFloat)time
{
    [self closeSoundTimer];
    _soundTimer = [NSTimer timerWithTimeInterval:time target:self selector:@selector(addAnimationToSoundeWaveLayer:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_soundTimer forMode:NSRunLoopCommonModes];
}

- (void)closeSoundTimer
{
    if (_soundTimer) {
        if ([_soundTimer isValid]) {
            [_soundTimer invalidate];
        }
        _soundTimer = nil;
    }
}

- (WaveObject *)gernerateWaveObject
{
    CAShapeLayer *waveLayer = [CAShapeLayer layer];
    waveLayer.bounds = CGRectMake(0, 0, _waveWidth, self.bounds.size.height);
    waveLayer.backgroundColor = [UIColor clearColor].CGColor;
    waveLayer.strokeColor = [UIColor whiteColor].CGColor;
    waveLayer.lineWidth = 1.0;
    waveLayer.opacity = 0.5;
    waveLayer.fillColor = [UIColor clearColor].CGColor;
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    
    [path moveToPoint:CGPointMake(0, self.bounds.size.height / 2)];
    
    [path addLineToPoint:CGPointMake(straightLineLength, self.bounds.size.height / 2)];
    
    [path addCurveToPoint:CGPointMake(_waveWidth - straightLineLength, self.bounds.size.height / 2) controlPoint1:CGPointMake(straightLineLength + (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2) controlPoint2:CGPointMake(straightLineLength + 3 * (_waveWidth - 2 * straightLineLength) / 4, self.bounds.size.height / 2)];
    
    [path addLineToPoint:CGPointMake(_waveWidth, self.bounds.size.height / 2)];
    waveLayer.path = path.CGPath;
    
    WaveObject *waveObject = [[WaveObject alloc] init];
    waveObject.shapeLayer = waveLayer;
    waveObject.height = 0.0;
    
    return waveObject;
}

- (void)removeFromParentView
{
    if (self.superview) {
        [self removeAllSubLayers];
        [self removeFromSuperview];
        [self closeWaveTimer];
        [self closeWaveTimer];
        [self closeSoundTimer];
        [_waveObjects removeAllObjects];
        [_soundWaveObjects removeAllObjects];
        [self.layer removeAllAnimations];
    }
}

- (void)removeAllSubLayers
{
    for (NSInteger i = 0; [self.layer sublayers].count > 0; i++) {
        [[[self.layer sublayers] firstObject] removeFromSuperlayer];
    }
}

- (void)closeWaveTimer
{
    if (_waveTimer) {
        if ([_waveTimer isValid]) {
            [_waveTimer invalidate];
        }
        _waveTimer = nil;
    }
}

@end
